package com.itany.nmms.service.impl;

import com.itany.nmms.constant.DictConstant;
import com.itany.nmms.dao.ProductMapper;
import com.itany.nmms.dao.SequenceMapper;
import com.itany.nmms.entity.Product;
import com.itany.nmms.entity.ProductExample;
import com.itany.nmms.entity.Sequence;
import com.itany.nmms.entity.SequenceExample;
import com.itany.nmms.exception.FileUploadErrorException;
import com.itany.nmms.exception.ProductExistException;
import com.itany.nmms.exception.RequestParameterErrorException;
import com.itany.nmms.service.ProductService;
import com.itany.nmms.util.ParameterUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Author:shixiaojun@itany.com
 * Date:2022/5/25 9:10
 * Version:1.0-SNAPSHOT
 * Description:
 */
@Service
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public class ProductServiceImpl implements ProductService {

    @Autowired
    private SequenceMapper sequenceMapper;
    @Autowired
    private ProductMapper productMapper;

    @Override
    public void addProduct(String name, String price, MultipartFile file, String typeId) throws RequestParameterErrorException, ProductExistException, FileUploadErrorException {
        if(ParameterUtil.isNull(name) || ParameterUtil.isNull(price) || file.isEmpty() || ParameterUtil.isNull(typeId)){
            throw new RequestParameterErrorException("请求参数有误");
        }

        // 同一种类型的商品不能重复
        ProductExample example = new ProductExample();
        example.or()
                .andNameEqualTo(name)
                .andProductTypeIdEqualTo(Integer.parseInt(typeId));
        List<Product> products = productMapper.selectByExample(example);
        if(!products.isEmpty()){
            throw new ProductExistException("该商品已经存在");
        }

        Product product = new Product();
        product.setProductTypeId(Integer.parseInt(typeId));
        product.setName(name);
        product.setPrice(Double.parseDouble(price));

        // 生成商品编号
        SequenceExample sequenceExample = new SequenceExample();
        sequenceExample.or()
                .andNameEqualTo(DictConstant.PRODUCT_NO_PREFIX);
        List<Sequence> sequences = sequenceMapper.selectByExample(sequenceExample);
        if(sequences.isEmpty()){
            // 如果没有查询到对应的序列号信息
            // 表示当前商品编号尚未生成过
            // 创建一组初始数据,插入到序列号表中
            Sequence sequence = new Sequence();
            sequence.setName(DictConstant.PRODUCT_NO_PREFIX);
            sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            sequenceMapper.insertSelective(sequence);

            // 并生成此时的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        } else{
            // 如果查询到对应的数据
            // 那么此时的数据有且仅有一条
            // 取出这一条数据
            Sequence sequence = sequences.get(0);
            // 判断当前序列号的值是否达到了最大值
            if(DictConstant.PRODUCT_NO_SEQUENCE_MAX_VALUE.equals(sequence.getValue())){
                sequence.setValue(DictConstant.PRODUCT_NO_SEQUENCE_INIT_VALUE);
            }else{
                sequence.setValue(ParameterUtil.nextValue(sequence.getValue()));
            }

            // 执行修改操作
            sequenceMapper.updateByPrimaryKeySelective(sequence);

            // 并生成此时的商品编号
            product.setProductNo(DictConstant.PRODUCT_NO_PREFIX+new SimpleDateFormat("yyyyMMdd").format(new Date())+sequence.getValue());
        }

        // 上传商品图片
        String path = DictConstant.PRODUCT_IMAGE_ROOT_FOLDER + new SimpleDateFormat("yyyyMMdd").format(new Date());



        try {
            // 获取当前绝对路径
//        String cp = session.getServletContext().getRealPath(path);
            String cp = ResourceUtils.getURL("classpath:").getPath()+path;
        System.out.println("************cp:"+cp);
            // 创建存放图片的目录
            File f = new File(cp);
            f.mkdirs();

            // 为了防止图片名称重复,为上传的每一张图片加一个毫秒数的后缀
            String fileName = file.getOriginalFilename();
            fileName = fileName.substring(0,fileName.lastIndexOf("."))+"-"+new Date().getTime()+fileName.substring(fileName.lastIndexOf("."));

            product.setImage(path+"/"+fileName);
            // 添加商品
            productMapper.insertSelective(product);
            // 上传商品图片
            file.transferTo(new File(cp,fileName));
        } catch (IOException e) {
            throw new FileUploadErrorException("文件上传失败");
        }

    }

    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public List<Product> findAll() {
        List<Product> products = productMapper.selectAll();
        return products;
    }

    @Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
    @Override
    public Product findById(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        Product product = productMapper.selectByPrimaryKey(Integer.parseInt(id));
        return product;
    }

    @Override
    public void modifyProduct(String id, String name, String price, MultipartFile file, String typeId) throws RequestParameterErrorException, ProductExistException, FileUploadErrorException {
        if(ParameterUtil.isNull(id) || ParameterUtil.isNull(name) || ParameterUtil.isNull(price) || ParameterUtil.isNull(typeId)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        // 同一种类型的商品不能重复
        // 数据库中存在且不是自己的则抛出异常
        ProductExample example = new ProductExample();
        example.or()
                .andNameEqualTo(name)
                .andProductIdNotEqualTo(Integer.parseInt(id))
                .andProductTypeIdEqualTo(Integer.parseInt(typeId));
        List<Product> products = productMapper.selectByExample(example);
        if(!products.isEmpty()){
            throw new ProductExistException("该商品已经存在");
        }
        Product product = new Product();
        product.setProductId(Integer.parseInt(id));
        product.setProductTypeId(Integer.parseInt(typeId));
        product.setName(name);
        product.setPrice(Double.parseDouble(price));

        if(!file.isEmpty()){
            // 当传递了商品图片则需要重新上传
            // 上传商品图片
            String path = DictConstant.PRODUCT_IMAGE_ROOT_FOLDER + new SimpleDateFormat("yyyyMMdd").format(new Date());



            try {
                // 获取当前绝对路径
//            String cp = session.getServletContext().getRealPath(path);
                String cp = ResourceUtils.getURL("classpath:").getPath()+path;
                // 创建存放图片的目录
                File f = new File(cp);
                f.mkdirs();

                // 为了防止图片名称重复,为上传的每一张图片加一个毫秒数的后缀
                String fileName = file.getOriginalFilename();
                fileName = fileName.substring(0,fileName.lastIndexOf("."))+"-"+new Date().getTime()+fileName.substring(fileName.lastIndexOf("."));

                product.setImage(path+"/"+fileName);
                productMapper.updateByPrimaryKeySelective(product);
                file.transferTo(new File(cp,fileName));
            } catch (IOException e) {
                throw new FileUploadErrorException("文件上传出错");
            }
        }else{
            // 当没有传递商品图片,则无需重新上传
            productMapper.updateByPrimaryKeySelective(product);
        }

    }

    @Override
    public void removeProduct(String id) throws RequestParameterErrorException {
        if(ParameterUtil.isNull(id)){
            throw new RequestParameterErrorException("请求参数有误");
        }
        productMapper.deleteByPrimaryKey(Integer.parseInt(id));
    }
}
